package com.ac.aop;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.bson.Document;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.ac.exception.RRException;
import com.ac.model.AuthToken;
import com.ac.response.HttpStatus;
import com.ac.service.AuthTokenService;

import ch.qos.logback.classic.Logger;

@Component
@Aspect
@SuppressWarnings({ "unused" })
public class AuthAspect {

	private static final Logger log = (Logger) LoggerFactory.getLogger(AuthAspect.class);

	@Autowired
	AuthTokenService ts;

	// 这里需要注意了，这个是将自己自定义注解作为切点的根据，路径一定要写正确了
	@Pointcut(value = "@annotation(com.ac.aop.Auth)")
	public void access() {
	}

	// 进来切点世界，先经过的第一个站
	@Before("access()")
	public void doBefore(JoinPoint joinPoint) throws Throwable {
//        System.out.println("-aop 日志记录启动-" + new Date(0));
	}

	// 环绕增强，是在before前就会触发，在执行控制器之前执行
	@Around("@annotation(Auth)")
	public Object around(ProceedingJoinPoint pjp, Auth Auth) throws Throwable {
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = attributes.getRequest();
		String token = request.getHeader("token");
		String url = request.getRequestURL().toString();// 用户访问的api地址
		url = url.split("//")[1];
		url = url.substring(url.indexOf("/"));
//		System.out.println(url);
//		System.out.println(token);
		Document tokenInfoDoc = ts.isToken(token);
		String str = "无操作权限，联系管理员";
		String str1 = "请登录后再试";
		boolean isToken = tokenInfoDoc.getBoolean("is");
		if (!isToken)
			throw new RRException(str1, HttpStatus.FORBIDDEN);
		AuthToken tokenInfo = (AuthToken) tokenInfoDoc.get("tokenInfo");
		if (tokenInfo == null)
			throw new RRException(str1, HttpStatus.FORBIDDEN);
		boolean isApi = ts.isApi(tokenInfo, url);
		if (!isApi)
			throw new RRException(str, HttpStatus.UNAUTHORIZED);
		return pjp.proceed();

	}

	// 进来切点这，最后经过的一个站，也是方法正常运行结束后
	@After("access()")
	public void after(JoinPoint joinPoint) {
//        System.out.println("-aop 日志记录结束-" + new Date(0));
	}

}
